home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / BSP Tree 1.2 / Sources / BSP Tree Demo / source / arcball.cp next >
Encoding:
Text File  |  1995-03-26  |  7.5 KB  |  119 lines  |  [TEXT/MMCC]

  1. //------------------------------------------------------------------------------
  2. //    File:                    arcball.cp
  3. //    Date:                    9/18/94
  4. //    Author:                Bretton Wade
  5. //                                (C) copyright Cornell Program of Computer Graphics
  6. //
  7. //    Description:    this file contains the class methods for Ken Shoemake's
  8. //                                ArcBall rotation controller
  9. //                                
  10. //                                This class presumes the existence of a number of drawing
  11. //                                routines, and a graphics system that uses Virtual Device
  12. //                                Coordinates ranging from -1 to 1 in both x and y. The
  13. //                                ArcBall itself and the feedback are projected orthographically
  14. //                                onto the screen.
  15. //                                
  16. //------------------------------------------------------------------------------
  17.  
  18. #include "draw.h"
  19. #include "colors.h"
  20. #include "arcball.h"
  21. #include "quaternion_3d.h"
  22.  
  23. //------------------------------------------------------------------------------
  24. //    constructor
  25. //------------------------------------------------------------------------------
  26. arcball::arcball (const point_2d ¢, real rad) : interface ()                                //    normal constructor
  27. {                                                                                                                                                                //    begin
  28.     center = vector_2d (cent);                                                                                                        //    store the center point_2d of the arcball
  29.     radius = rad;                                                                                                                                    //    store the radius of the arcball
  30. }                                                                                                                                                                //    end
  31.  
  32. //------------------------------------------------------------------------------
  33. //    take begin of drag
  34. //------------------------------------------------------------------------------
  35. void    arcball::Click (const point_2d &pt)                                                                                //    the first point_3d in the arc
  36. {                                                                                                                                                                //    begin
  37.     start_vec = MapToSphere (pt - center);                                                                                //    map the point_3d to the arcball sphere
  38.     start_pt = point_2d (start_vec[X], start_vec[Y]) + center;                                        //    save the mapped vector_3d as a point_3d too
  39. }                                                                                                                                                                //    end
  40.  
  41. //------------------------------------------------------------------------------
  42. //    complete drag
  43. //------------------------------------------------------------------------------
  44. matrix_3d    arcball::Drag (const point_2d &pt)                                                                        //    the second point_3d in the arc
  45. {                                                                                                                                                                //    begin
  46.     end_vec = MapToSphere (pt - center);                                                                                    //    map the point_3d to the arcball sphere
  47.     end_pt = point_2d (end_vec[X], end_vec[Y]) + center;                                                    //    save the mapped vector_3d as a point_3d too
  48.     return Quaternion (start_vec, end_vec);                                                                                //    return the matrix_3d equivalent to the quaternion
  49. }                                                                                                                                                                //    end
  50.  
  51. //------------------------------------------------------------------------------
  52. //    draw the sphere of the arcball
  53. //------------------------------------------------------------------------------
  54. void    arcball::DrawBackground (void) const                                                                            //    draw the sphere
  55. {                                                                                                                                                                //    begin
  56.     RGBBackColor (&HILITE_COLOR);                                                                                                    //    set the background color
  57.     RGBForeColor (&MID_HILITE_COLOR);                                                                                            //    set the foreground color
  58.     point_2d    A = point_2d (-radius, -radius) + center,                                                        //    compute the bottom left point_3d of a rectangle
  59.                         B = point_2d (radius, radius) + center;                                                            //    compute the top right of a rectangle
  60.     Circle (A, B);                                                                                                                                //    draw a circle inside the rectangle in the view
  61.     RGBBackColor (&WHITE);                                                                                                                //    restore the background color, no need to restore the foreground color for me
  62.     RGBForeColor (&BLACK);                                                                                                                //    reset the foreground color
  63. }                                                                                                                                                                //    end
  64.  
  65. //------------------------------------------------------------------------------
  66. //    draw all the arcball feedback
  67. //------------------------------------------------------------------------------
  68. void    arcball::DrawForeground (void) const                                                                            //    draw the arcball interface
  69. {                                                                                                                                                                //    begin
  70.     RGBForeColor (&BLUE);                                                                                                                    //    set the foreground color
  71.     DrawArc (5);                                                                                                                                    //    draw the great arc on the arcball sphere
  72.     RGBForeColor (&RED);                                                                                                                    //    set the foreground color
  73.     CrossHair (end_pt);                                                                                                                        //    draw a crosshair at the end point_3d
  74.     RGBForeColor (&BLACK);                                                                                                                //    reset the foreground color
  75.     CrossHair (start_pt);                                                                                                                    //    draw a crosshair at the atrt point_3d
  76. }                                                                                                                                                                //    end
  77.  
  78. //------------------------------------------------------------------------------
  79. //    compute the segments on the feedback arc
  80. //------------------------------------------------------------------------------
  81. void    arcball::ComputeArc (short segs, const vector_3d &a, const vector_3d &b) const    //    compute the arc between two points with the given number of segments
  82. {                                                                                                                                                                //    begin
  83.     if (segs)                                                                                                                                            //    if more segments need to be computed
  84.     {                                                                                                                                                            //    begin
  85.         vector_3d    bisector = (a + b).Normalize () * radius;                                                    //    compute the vector_3d that bisects the angle between 'a' and 'b'
  86.         ComputeArc (segs - 1, a, bisector);                                                                                    //    compute the sub arc from 'a' to the 'bisector'
  87.         ComputeArc (segs - 1, bisector, b);                                                                                    //    compute the sub arc from the 'bisector' to 'b'
  88.     }                                                                                                                                                            //    end
  89.     else                                                                                                                                                    //    otherwise
  90.         LineTo (point_2d (b[X], b[Y]) + center);                                                                        //    draw a line to the segment endpoint
  91. }                                                                                                                                                                //    end
  92.  
  93. //------------------------------------------------------------------------------
  94. //    draw the feedback arc
  95. //------------------------------------------------------------------------------
  96. void    arcball::DrawArc (short numsegs) const                                                                        //    draw the arc between the two points
  97. {                                                                                                                                                                //    begin
  98.     MoveTo (start_pt);                                                                                                                        //    move the pen to the start_vec point_3d
  99.     ComputeArc (numsegs, start_vec, end_vec);                                                                            //    compute the arc and draw each segment
  100. }                                                                                                                                                                //    end
  101.  
  102. //------------------------------------------------------------------------------
  103. //    map some click point_3d to the arcball sphere
  104. //------------------------------------------------------------------------------
  105. vector_3d    arcball::MapToSphere (const point_2d &pt)                                                            //    compute the intersection pt of the arcball with a line to the point_3d
  106. {                                                                                                                                                                //    begin
  107.     real    r = (pt[X] * pt[X]) + (pt[Y] * pt[Y]),                                                                    //    compute the square of the length of the vector_3d to the point_3d from the center
  108.                 radsq = radius * radius;                                                                                                //    compute the square of the radius of the arcball sphere
  109.     if (r > radsq)                                                                                                                                //    if the point_3d is mapped outside of the arcball sphere
  110.     {                                                                                                                                                            //    begin
  111.         real    s = radius / SQRT (r);                                                                                                //    compute a normalizing factor
  112.         return vector_3d (pt[X] * s, pt[Y] * s, R(0.0));                                                        //    return the "normalized" vector_3d, a point_3d on the sphere
  113.     }                                                                                                                                                            //    end
  114.     else                                                                                                                                                    //    alse
  115.         return vector_3d (pt[X], pt[Y], SQRT (radsq - r));                                                    //    return a vector_3d to a point_3d mapped inside the sphere
  116. }                                                                                                                                                                //    end
  117.  
  118. //------------------------------------------------------------------------------
  119.